//package com.boot2.core.conf;
//
//import com.boot2.core.utils.SpringUtil;
//import lombok.extern.apachecommons.CommonsLog;
//import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
//import org.springframework.beans.MutablePropertyValues;
//import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
//import org.springframework.beans.factory.config.BeanDefinitionHolder;
//import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
//import org.springframework.beans.factory.support.BeanDefinitionRegistry;
//import org.springframework.context.annotation.*;
//import org.springframework.transaction.PlatformTransactionManager;
//import org.springframework.transaction.interceptor.TransactionInterceptor;
//import org.springframework.util.Assert;
//
//import java.util.HashSet;
//import java.util.Properties;
//import java.util.Set;
//
///**
// * @author zhangweilin
// * @date 2018/11/24 21:05
// * @description: 全局声明式事务(此配置解决事务内修改不可见问题, 而另一个却事务内修改不可见, 此坑消耗了我整整两天一夜研究琢磨, )
// * 在一个系统只有一个数据源情况下，任何一个工程中不需要再有额外的配置，只需要此配置即可，但是有多数据源时，可基于此创建多数据源的事务
// */
////@Component
//@Configuration
//@CommonsLog
//public class TxConfig2 {
//    //    @Autowired
////    private PlatformTransactionManager transactionManager;
//    private static final Properties transactionProperties = new Properties();
//    private static final Set<String> txInterceptorNameSet = new HashSet<>();
//
//    static {
//        /**
//         * 所有的事务拦截器都走统一的事务规则
//         */
//        transactionProperties.setProperty("init*", "PROPAGATION_REQUIRED,-Exception");
//        transactionProperties.setProperty("add*", "PROPAGATION_REQUIRED,-Exception");
//        transactionProperties.setProperty("insert*", "PROPAGATION_REQUIRED,-Exception");
//        transactionProperties.setProperty("create*", "PROPAGATION_REQUIRED,-Exception");
//        transactionProperties.setProperty("persist*", "PROPAGATION_REQUIRED,-Exception");
//        transactionProperties.setProperty("update*", "PROPAGATION_REQUIRED,-Exception");
//        transactionProperties.setProperty("modify*", "PROPAGATION_REQUIRED,-Exception");
//        transactionProperties.setProperty("merge*", "PROPAGATION_REQUIRED,-Exception");
//        transactionProperties.setProperty("bind*", "PROPAGATION_REQUIRED,-Exception");
//        transactionProperties.setProperty("del*", "PROPAGATION_REQUIRED,-Exception");
//        transactionProperties.setProperty("drop*", "PROPAGATION_REQUIRED,-Exception");
//        transactionProperties.setProperty("remove*", "PROPAGATION_REQUIRED,-Exception");
//        transactionProperties.setProperty("reset*", "PROPAGATION_REQUIRED,-Exception");
//        transactionProperties.setProperty("cancel*", "PROPAGATION_REQUIRED,-Exception");
//        transactionProperties.setProperty("login*", "PROPAGATION_REQUIRED,-Exception");
//        transactionProperties.setProperty("save*", "PROPAGATION_REQUIRED,-Exception");
//        transactionProperties.setProperty("update*", "PROPAGATION_REQUIRED,-Exception");
//        transactionProperties.setProperty("delete*", "PROPAGATION_REQUIRED,-Exception");
//
//        transactionProperties.setProperty("get", "PROPAGATION_REQUIRED,-Exception,readOnly");
//        transactionProperties.setProperty("select", "PROPAGATION_REQUIRED,-Exception,readOnly");
//        transactionProperties.setProperty("find", "PROPAGATION_REQUIRED,-Exception,readOnly");
//        transactionProperties.setProperty("query", "PROPAGATION_REQUIRED,-Exception,readOnly");
//        transactionProperties.setProperty("load", "PROPAGATION_REQUIRED,-Exception,readOnly");
//        transactionProperties.setProperty("list", "PROPAGATION_REQUIRED,-Exception,readOnly");
//        transactionProperties.setProperty("show", "PROPAGATION_REQUIRED,-Exception,readOnly");
//        transactionProperties.setProperty("fech", "PROPAGATION_REQUIRED,-Exception,readOnly");
//    }
//
//    private BeanNameAutoProxyCreator beanNameAutoProxyCreator;
//
//
////    /**
//////     * 当多数据源时，动态添加各数据源需要的事务名称
//////     * @param txInterceptorName
//////     */
//////    public void addTxInterceptorName(String txInterceptorName) {
//////        txInterceptorNameSet.add(txInterceptorName);
//////    }
//
//    /**
//     * 当多数据源时，动态添加各数据源需要的事务
//     *
//     * @param transactionManager
//     */
////    public void addTransaction(String datasourceName, PlatformTransactionManager transactionManager) {
////        Assert.notNull(beanNameAutoProxyCreator, "默认事务还未创建，无法动态添加");
////        TransactionInterceptor tsi = new TransactionInterceptor(transactionManager, transactionProperties);
////        String txInterceptorName = "txAdvice" + datasourceName;
////        txInterceptorNameSet.add(txInterceptorName);
////        SpringUtil.regExistingBean(txInterceptorName, tsi);
////        log.info("成功注册事务拦截器:"+txInterceptorName);
////        String[] txInterceptorNameArr = txInterceptorNameSet.toArray(new String[]{});
//////        CollectionUtils.addAll(txInterceptorNameSet, txInterceptorNameArr);
////        beanNameAutoProxyCreator.setInterceptorNames(txInterceptorNameArr);
////    }
//
////    /**
////     * 当多数据源时，动态添加各数据源需要的事务
////     *
////     * @param transactionManager
////     */
////    public void addTransaction(String datasourceName, PlatformTransactionManager transactionManager) {
////        Assert.notNull(beanNameAutoProxyCreator, "默认事务还未创建，无法动态添加");
//////        TransactionInterceptor tsi = new TransactionInterceptor(transactionManager, transactionProperties);
////        String txInterceptorName = "txAdvice" + datasourceName;
////        txInterceptorNameSet.add(txInterceptorName);
////
////        ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
//////        BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
////        BeanDefinitionRegistry registry = SpringUtil.getRegistry();
////        AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(TransactionInterceptor.class);
////        MutablePropertyValues propertyValues = abd.getPropertyValues();
////        propertyValues.addPropertyValue("transactionManager", transactionManager);
////        propertyValues.addPropertyValue("transactionAttributes", transactionProperties);
//////        abd.setAttribute("transactionManager", transactionManager);
//////        abd.setAttribute("transactionAttributes", transactionProperties);
////        ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(abd);
////        abd.setScope(scopeMetadata.getScopeName());
////        AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
////        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, txInterceptorName);
////        BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
////
//////        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TransactionInterceptor.class);
////        Object bean = SpringUtil.getBean(txInterceptorName);
////        log.info("成功注册事务拦截器:" + txInterceptorName+", bean: "+bean);
//////        String[] txInterceptorNameArr = txInterceptorNameSet.toArray(new String[]{});
//////        CollectionUtils.addAll(txInterceptorNameSet, txInterceptorNameArr);
//////        beanNameAutoProxyCreator.setInterceptorNames(txInterceptorNameArr);
////    }
//
//
//    /**
//     * 由spring自启动时创建的默认事务拦截器
//     *
//     * @param transactionManager
//     * @return
//     * @throws Exception
//     */
//    @Bean(name = "txAdvice")
//    public TransactionInterceptor createTransactionInterceptor(PlatformTransactionManager transactionManager) throws Exception {
//        System.out.println("transactionManager = " + transactionManager);
//        TransactionInterceptor tsi = new TransactionInterceptor(transactionManager, transactionProperties);
//        return tsi;
//    }
//
//    @Bean
//    @Primary
//    public BeanNameAutoProxyCreator txProxy() {
//        BeanNameAutoProxyCreator creator = new BeanNameAutoProxyCreator();
////        creator.setInterceptorNames("txAdvice");
//        //拦截器名字不能提前加，需要先有bean才能加,要先有bean，,而在后期动态添加的拦截器名字无效
//        txInterceptorNameSet.add("dynamicDataInterceptor");
//        txInterceptorNameSet.add("txAdvice");
//        //直接加上下面两句,不管对应的拦截器是用代码创建还是用@Bean创建，全部事务都无效，目前没找到原因
//        //所以非主数据源也用自动事务的尝试失败了，目前只能做到：主事务是自动的，非主事务，需要手动在方法头上加@Transactional("transactionManagerTest3")
////        txInterceptorNameSet.add("txAdviceTest2");
////        txInterceptorNameSet.add("txAdviceTest3");
//        creator.setInterceptorNames(txInterceptorNameSet.toArray(new String[]{}));
//        creator.setBeanNames("*Service", "*Dao");
//        creator.setProxyTargetClass(true);
//        this.beanNameAutoProxyCreator = creator;
//        return creator;
//    }
//}